package org.redrock.test.interceptor;

import com.google.gson.Gson;
import org.redrock.test.exception.WeixinException;
import org.redrock.test.interceptor.annotation.Auth;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Component
public class InitInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
        httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
        if (handler != null) {
            if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
                Annotation[] methodAnnotations = ((HandlerMethod)handler).getMethod().getAnnotations();
                for (int i = 0; i < methodAnnotations.length; i++) {
                    Annotation annotation = methodAnnotations[i];
                    Auth auth = null;
                    try { auth = (Auth) annotation; } catch (Exception e) {}
                    if (auth != null) {
                        try {
                            Class<? extends BaseInterceptor> interceptor = auth.value();
                            Object object = Class.forName(interceptor.getCanonicalName()).newInstance();
                            Class[] clazzes = new Class[]{HttpServletRequest.class, HttpServletResponse.class, Object.class};
                            Method method = object.getClass().getMethod("interceptor", clazzes);
                            Object[] params = new Object[]{httpServletRequest, httpServletResponse, handler};
                            boolean status = (boolean) method.invoke(object, params);
                            if (!status) return false;
                        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                            Throwable cause = e.getCause();
                            if(cause instanceof WeixinException){
                                Map data = new HashMap();
                                httpServletResponse.setContentType("application/json;charset=UTF-8");
                                data.put("msg", ((WeixinException) cause).getErrorMsg());
                                httpServletResponse.setStatus(((WeixinException) cause).getHttpStatus().value());
                                httpServletResponse.getWriter().println(new Gson().toJson(data));
                                return false;
                            }
                        }
                    }
                }
            }

        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
